﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Hikvision.Ys;
using Hikvision.Ys.Containers;
using Hikvision.Ys.DeviceApis;
using Hikvision.Ys.iVMS.Camera;
using Hikvision.Ys.iVMS9800;
using IiiToolkitMain.Controls;

namespace IiiToolkitMain
{
    public partial class _9800Form : Form
    {
        public _9800Form()
        {
            InitializeComponent();
        }

        //摄像头对讲机
        public static string sysCode = ConfigurationSettings.AppSettings["SysCode"].ToString();
        //9800服务器地址
        public static string cmsServerUrl = ConfigurationSettings.AppSettings["CmsServerUrl"].ToString();
        //9800用户名
        public static string hkUser = ConfigurationSettings.AppSettings["HkUser"].ToString();
        //9800用户密码
        public static string hkPass = ConfigurationSettings.AppSettings["HkPass"].ToString();
        //9800接口
        private SdkCenter sdkCenter;
        //凯泉服务器图片信息接收地址
        public static string kqUrl = ConfigurationSettings.AppSettings["KqUrl"].ToString();
        //图片服务器接收地址
        public static string saveImgUrl = ConfigurationSettings.AppSettings["SaveImgUrl"].ToString();
        //图片服务器接收API
        public static string saveImgApi = ConfigurationSettings.AppSettings["saveImgApi"].ToString();

        private void _9800Form_Load(object sender, EventArgs e)
        {
            GetLiveAddress();
        }
        /// <summary>
        /// 获取9800播放地址
        /// </summary>
        private void GetLiveAddress()
        {
            var cameraInfo = SyncDeviceData(new string[] { sysCode }).First(x => x.sysCode.Equals(sysCode));

            string liveAddress = string.Format("{0}/previewCas?indexCode={1}&userName={2}&password={3}",
                cmsServerUrl,
                cameraInfo.sysCode,
                hkUser,
                SHA256(hkPass)
                );
            this.webBrowser9800.Navigate(liveAddress);
        }


        //密码加密
        private static string SHA256(string strData)
        {
            byte[] bytValue = System.Text.Encoding.UTF8.GetBytes(strData);
            try
            {
                SHA256 sha256 = new SHA256CryptoServiceProvider();
                byte[] retVal = sha256.ComputeHash(bytValue);
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < retVal.Length; i++)
                {
                    sb.Append(retVal[i].ToString("x2"));
                }
                return sb.ToString();
            }
            catch (Exception ex)
            {
                throw new Exception("GetSHA256HashFromString() fail,error:" + ex.Message);
            }
        }
        /// <summary>
        /// 获取9800设备
        /// </summary>
        /// <param name="sysCodes"></param>
        /// <returns></returns>
        public IPagedList<CameraInfo> SyncDeviceData(string[] sysCodes)
        {
            var url = "http://" + cmsServerUrl.Replace("http://", "").TrimEnd('/');

            sdkCenter = SdkCenterWindow.GetSdkCenter(url, hkUser);
            if (sdkCenter == null)
            {
                try
                {
                    sdkCenter = SdkCenterWindow.CreateSdkCenter(url, hkUser, hkPass);
                }
                catch (Exception)
                {

                    MessageBox.Show("访问失败，刷新试试看！");
                }
            }
            var videoList = new List<CameraInfo>();
            var pageSize = 10;
            var result = (sysCodes == null || sysCodes.Length < 1)
                ? sdkCenter.GetResourceByPage(SdkCenter.ResourceType.Video, 1, pageSize)
                : sdkCenter.GetResourceByIndexCodes(SdkCenter.ResourceType.Video, sysCodes);

            if (result.Total > 0)
            {
                foreach (var row in result.Rows)
                {
                    var info = new CameraInfo
                    {
                        cameraChannel = Convert.ToInt32(row["i_channel_no"]),
                        cameraName = Convert.ToString(row["c_name"]),
                        cameraType = Convert.ToInt32(row["i_camera_type"]),
                        encoderSysCode = "",
                        sysCode = Convert.ToString(row["c_index_code"]),
                        onlineStatus = Convert.ToInt32(row["i_is_online"])
                    };
                    if (string.IsNullOrEmpty(info.sysCode) || info.sysCode == "null") continue;
                    videoList.Add(info);
                }
                var pageCount = Math.Ceiling(result.Total / (double)result.PageSize);
                if (pageCount > 1)
                {
                    for (int pageStart = 2; pageStart <= pageCount; pageStart++)
                    {
                        var tempList = Get9800CameraList(sdkCenter, pageStart, result.PageSize);
                        if (tempList != null && tempList.Count > 0)
                        {
                            videoList.AddRange(tempList);
                        }
                    }
                }
            }
            return new PagedList<CameraInfo>(videoList, 1, videoList.Count, videoList.Count);
        }

        private List<CameraInfo> Get9800CameraList(SdkCenter sdkCenter, int pageStart, int pageSize)
        {
            var result = sdkCenter.GetResourceByPage(SdkCenter.ResourceType.Video, pageStart, pageSize);

            if (result.Rows != null && result.Rows.Count > 0)
            {
                var videoList = new List<CameraInfo>();
                foreach (var row in result.Rows)
                {
                    var info = new CameraInfo
                    {
                        cameraChannel = Convert.ToInt32(row["i_channel_no"]),
                        cameraName = Convert.ToString(row["c_name"]),
                        cameraType = Convert.ToInt32(row["i_camera_type"]),
                        encoderSysCode = "",
                        sysCode = Convert.ToString(row["c_index_code"]),
                        onlineStatus = Convert.ToInt32(row["i_is_online"])
                    };
                    if (string.IsNullOrEmpty(info.sysCode) || info.sysCode == "null") continue;
                    videoList.Add(info);
                }
                return videoList;
            }
            return null;
        }


        private void webBrowser9800_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {

        }

        /// <summary>
        /// 还原
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnNor_Click(object sender, EventArgs e)
        {
            WindowState = FormWindowState.Normal;
        }

        /// <summary>
        /// 最大化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnMax_Click(object sender, EventArgs e)
        {
            WindowState = FormWindowState.Maximized;
        }

        /// <summary>
        /// 最小化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnMin_Click(object sender, EventArgs e)
        {
            WindowState = FormWindowState.Minimized;
        }
        /// <summary>
        /// 刷新
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRef_Click(object sender, EventArgs e)
        {
            //this.webBrowser9800.Navigate("http://140.207.158.228:89/vms/web/module/preview/indexCas.action?indexCode=" + sysCode);
            GetLiveAddress();
        }

        private List<CapturePicture> pictures = new List<CapturePicture>();
        /// <summary>
        /// 拍照
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            var picAddress = sdkCenter.SnapPictureShow(sysCode);
            //DebugHelper.Info(picAddress);
            if (!string.IsNullOrEmpty(picAddress))//调用SDK截图方法
            {
                var picture = new CapturePicture()
                {
                    CreateTime = DateTime.Now
                };
                picture.SetPicture(picAddress);
                picture.Width = pnlCapturePictureList.Width - 24;
                picture.Margin = new Padding(3);
                picture.OnPictureClick += Picture_OnPictureClick;
                pictures.Add(picture);

                DisplayCapturePictures();
            }
            else
            {
                MessageBox.Show("拍照失败", "提示", MessageBoxButtons.OK);
            }
        }

        /// <summary>
        /// 拍照倒序
        /// </summary>
        private void DisplayCapturePictures()
        {
            this.pnlCapturePictureList.Controls.Clear();
            var pics = pictures.OrderByDescending(x => x.CreateTime);
            foreach (var capturePicture in pics)
            {
                this.pnlCapturePictureList.Controls.Add(capturePicture);
            }
        }

        //点击图片
        private void Picture_OnPictureClick(object sender, CapturePictureEventArgs e)
        {
            PictureBox pic = (PictureBox)sender;
            ImgFrom imgf = new ImgFrom();
            imgf.ShowDialog();
            int num = 0;
            string desc = "";
            if (imgf.DialogResult == DialogResult.OK)
            {
                num = imgf.Num;
                desc = imgf.Desc;
                Upload(num, desc, pic);
            }
        }



        ///// <summary>
        ///// 上传图片
        ///// </summary>
        ///// <param name="num">星级</param>
        ///// <param name="desc">描述</param>
        private void Upload(int num, string desc, PictureBox pic)
        {
            byte[] bytes;
            if (string.IsNullOrEmpty(pic.ImageLocation))
            {
                MessageBox.Show("请选择上传的图片!");
            }
            button1.Enabled = false;
            btnClear.Enabled = false;
            bytes = SaveImage(pic.Image);
            //向图片服务器上传图片流返回保存的地址
            var result = ImageRequest(bytes);
            if (result == "error")
            {
                MessageBox.Show("图片上传失败");
            }
            else
            {
                //向凯泉上传图片信息
                var imgUrl = saveImgUrl + result;
                var rlImgUrl = imgUrl.Replace("\\", "/");
                if (ImageSave(rlImgUrl, num, desc))
                {
                    MessageBox.Show("图片信息上传成功");
                }
                else
                {
                    MessageBox.Show("图片信息上传失败");
                }
            }
            button1.Enabled = true;
            btnClear.Enabled = true;
        }

        public byte[] SaveImage(Image image)
        {
            MemoryStream ms = new MemoryStream();
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, (object)image);
            ms.Close();
            return ms.ToArray();

            //MemoryStream mStream = new MemoryStream();
            //imageStream.Save(mStream, ImageFormat.Jpeg);
            //BinaryReader br = new BinaryReader(mStream);
            //byte[] imgBytes = br.ReadBytes((int)mStream.Length);
            //return imgBytes;

        }

        /// <summary>
        /// 上传图片流到图片服务器
        /// </summary>
        /// <param name="data">图片流</param>
        /// <param name="num">星级</param>
        /// <param name="desc">描述</param>
        /// <returns>返回图片路径</returns>
        private string ImageRequest(byte[] data)
        {
            string url = saveImgUrl + saveImgApi;
            HttpWebResponse httpResponse = null;
            HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url);
            httpRequest.Method = "POST";
            //string paramStr = string.Format("num={0}&desc={1}", num, desc);
            //byte[] paramByte = Encoding.UTF8.GetBytes(paramStr);
            ////合并参数和图片byte数据
            //byte[] nowBytes = paramByte.Concat(data).ToArray();
            //httpRequest.Headers.Add("DataSize", nowBytes.Length.ToString());
            httpRequest.Headers.Add("ParamSize", data.Length.ToString());
            using (Stream stream = httpRequest.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
                stream.Close();
            }
            try
            {
                httpResponse = (HttpWebResponse)httpRequest.GetResponse();
            }
            catch (WebException ex)
            {
                httpResponse = (HttpWebResponse)ex.Response;
                button1.Enabled = true;
                btnClear.Enabled = true;
            }
            //响应流
            Stream st = httpResponse.GetResponseStream();
            StreamReader reader = new StreamReader(st, Encoding.GetEncoding("utf-8"));
            string result = reader.ReadToEnd();
            return result;
        }

        /// <summary>
        /// 向凯泉服务器上传图片保存信息
        /// </summary>
        /// <param name="path">保存路径</param>
        /// <param name="num">星级</param>
        /// <param name="desc">描述</param>
        /// <returns></returns>
        private bool ImageSave(string path, int num, string desc)
        {
            string url = kqUrl;
            HttpWebResponse httpResponse = null;
            HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url);
            httpRequest.Method = "POST";
            //定义参数
            string paramStr = string.Format("num={0}&desc={1}&imgUrl={2}", num, desc, path);
            byte[] bytes = Encoding.UTF8.GetBytes(paramStr);
            //写入请求流
            httpRequest.Headers.Add("ParamSize", bytes.Length.ToString());
            using (Stream st = httpRequest.GetRequestStream())
            {
                st.Write(bytes, 0, bytes.Length);
                st.Close();
            }
            try
            {
                httpResponse = (HttpWebResponse)httpRequest.GetResponse();
            }
            catch (WebException ex)
            {

                httpResponse = (HttpWebResponse)ex.Response;
                button1.Enabled = true;
                btnClear.Enabled = true;
            }

            //响应流
            Stream stream = httpResponse.GetResponseStream();
            StreamReader rd = new StreamReader(stream, Encoding.GetEncoding("utf-8"));
            string result = rd.ReadToEnd();
            if (result == "ok")
                return true;
            return true;
        }
        /// <summary>
        /// 清空
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClear_Click(object sender, EventArgs e)
        {
            pictures.Clear();
            DisplayCapturePictures();
        }

        private void pnlCapturePictureList_Paint(object sender, PaintEventArgs e)
        {

        }
    }
}
